#include <iostream>;

using std::cout;
using std::endl;

#define TRACE(object) cout << object << endl

namespace part1
{

	namespace Neumont
	{
		class Student
		{
		public:
			void report()
			{ TRACE("Student from Neumont"); }
		};
	}

	namespace University
	{
		class Student
		{
		public:
			void report()
			{ TRACE("Student from University"); }
		};
	}

	/**
	* Wrestle part 1
	* Namespaces
	*
	**/
	void part1()
	{
		Neumont::Student student1;
		University::Student student2;

		student1.report();
		student2.report();
	}

}


namespace part2
{
	namespace someNameSpace
	{
		#define HELLO "Hello World!"
		const char *hello = "Hello World!";
	}

	/**
	* Part 2 
	* Defines
	*
	**/
	void part2()
	{
		// defines do not have scope, they can be used anywhere as long as the preprocessor 
		// finds the definition before it is used. Since it does a cut-paste with the definitions,
		// the compiler cannot validate a define's scope. This allows you to use them anywhere
		cout << HELLO << endl;

		// here as an alternative, we use a const variable to 
		// enfore the need for a namespace while providing all the same
		// functionality as a #define
		cout << someNameSpace::hello << endl;
	}
}

namespace part3
{
	/**
	* Part 3
	* Hex, Binary
	**/
	void part3()
	{
		// by using the prefix 0x, you are effectively telling
		// the compiler that the following expression should be interpretted
		// as a hexadecimal value
		int value = 0xC3;
		TRACE(value);

		cout << std::hex() << value << endl;
	}
}

void main()
{
	//part1::part1();
	//part2::part2();
	//part3::part3();
}